﻿;@Ahk2Exe-SetMainIcon tools.ico  ; 指定托盘图标文件
;@Ahk2Exe-AddResource tools.ico, 160  ; 替换自带的'蓝色H'图标
;@Ahk2Exe-AddResource tools.ico, 207  ; 替换自带的'红色H'图标
;@Ahk2Exe-ExeName %A_ScriptDir%\五笔划译助手.exe  ; 打包后的exe文件路径
;@Ahk2Exe-SetCompanyName 98五笔资源库  ; 企业信息
;@Ahk2Exe-SetCopyright 98五笔资源库  ; 版权信息
;@Ahk2Exe-SetDescription 五笔划译助手  ; 文件说明
;@Ahk2Exe-SetFileVersion 1.5.3.0  ; 文件版本
;@Ahk2Exe-SetInternalName 五笔划译助手  ; 文件内部名
;@Ahk2Exe-SetLanguage 0x0804  ; 区域语言
;@Ahk2Exe-SetName 五笔划译助手  ; 名称
;@Ahk2Exe-SetProductName 五笔划译助手  ; 产品名称
;@Ahk2Exe-SetProductVersion 1.5.3.0  ; 产品版本号
;@Ahk2Exe-SetVersion 1.5.3.0  ; 版本号


#NoEnv
#MaxMem 2048
;#NoTrayIcon
#SingleInstance, Force
SetBatchLines, -1
#MaxThreadsPerHotkey 100
#MaxHotkeysPerInterval 400
#Persistent
#WinActivateForce
#Include %A_ScriptDir%
CoordMode,Mouse,Screen
#Include <Gdip_all>
#Include <ImagePut>
#Include <class_EasyIni>
#Include <BTT>
OnMessage(0x200, "WM_MOUSEMOVE")
OnExit,OnExits
;=====================================环境检测======================================================

if (A_AhkVersion<1.1.33){
	MsgBox,262160,Error,ahk主程序版本过低，要求1.1.33+,20
	ExitApp
}
if Not A_OSVersion~="i)^(WIN\_7|WIN\_8|\d+)"{
	MsgBox,262160,Error,仅支持Win7及Win7以上系统！,20
	ExitApp
}
If A_IsCompiled {
	thisPID := DllCall("GetCurrentProcessId")
	if objCount(Processlist:=GetProcessNameList(A_ScriptName))>1
	{
		loop,% objCount(Processlist)
		{
			if (thisPID<>Processlist[A_Index,2]){
				process,Close,% Processlist[A_Index,2]
			}
		}
	}
}Else{
	DetectHiddenWindows, On
	thisPID := DllCall("GetCurrentProcessId")
	WinGet, List, List,%A_ScriptName%
	Loop % List
	{
		WinGet, PID, PID, % "ahk_id " List%A_Index%
		WinGetTitle, WinTitle , % "ahk_id " List%A_Index%
		If (PID != thisPID&&WinTitle=A_ScriptName){
			process,Close,% PID
		}
	}
	DetectHiddenWindows, Off
}
TrayRefresh()
if !FileExist(A_Temp "\MouseSelectedTool"){
	FileCreateDir,%A_Temp%\MouseSelectedTool
}
FileInstall,CharacterData.txt,%A_Temp%\MouseSelectedTool\CharacterData.txt,1
FileInstall,Font\98WB-0.otf,%A_Temp%\MouseSelectedTool\98WB-0.otf,1
FileInstall,Font\98WB-3.otf,%A_Temp%\MouseSelectedTool\98WB-3.otf,1
FileInstall,Font\newma.ttf,%A_Temp%\MouseSelectedTool\newma.ttf,1
Menu, TRAY, NoStandard
Menu, TRAY, DeleteAll
Menu, Tray, UseErrorLevel
Menu, TRAY,Color, ffffff
Menu, TRAY,Add, 关于,OnAbout
Menu, TRAY,Add
Menu, TRAY,Add, 重载,OnReload
Menu, TRAY,Add,
Menu, TRAY,Add, 退出,OnExits
Menu, TRAY,Tip,% "划译助手x" A_PtrSize*8 "`n - 鼠标左键划选字符`n - 滚轮中键即可显示反查结果`n - 方向键切换显示结果"
if !A_IsCompiled {
	Menu, TRAY,Icon,tools.ico
}
SetTimer,EmptyMemoryTimer,On
Global selectpos:=1,pagenum:=0
Global RvlkFileData:=GetRvlkFileData()
Hotkey,$MButton,SetMouseRlk,On
CustomTrayTip("操作通知","鼠标左键划选字符，按下滚轮中键即可显示反查结果！方向键切换显示结果。",1,A_HOUR>5&&A_HOUR<18?false:True)
TrayRefresh(),EmptyMem()

#if WinExist("ahk_id " RvlkGui)||objlength(Rvlk_Array)
	$WheelUp::
	$Left::
		Critical
		MouseXpos:=RvlkObj[3,3],MouseYpos:=RvlkObj[3,4]
		if (selectpos=1&&pagenum>0){
			pagenum--,selectpos:=6
			Gosub split_Page
		}Else if (selectpos=1&&pagenum=0&&Ceil(objlength(Rvlk_Array)/6)>1) {
			pagenum:=Ceil(objlength(Rvlk_Array)/6)-1,selectpos:=Mod(objlength(Rvlk_Array),6)?Mod(objlength(Rvlk_Array),6):6
			Gosub split_Page
		}Else{
			selectpos:=selectpos>objlength(TextObj)?1:selectpos<2?objlength(TextObj):selectpos-1
			Gosub MatchCandidate
		}
		if WinExist("ahk_id " BttObj.HWND)&&objlength(RvlkObj){
			ZGList:=GetSelectZGList(RvlkObj[3,5],False)
			BttObj:=btt(ZGList, , , 1, BttStyle, {CoordMode:"Screen"})
		}
	Return

	$WheelDown::
	$Right::
		Critical
		MouseXpos:=RvlkObj[3,3],MouseYpos:=RvlkObj[3,4]
		if (selectpos=6&&pagenum<Ceil(objlength(Rvlk_Array)/6)-1){
			pagenum++,selectpos:=1
			Gosub split_Page
		}Else if (selectpos=objlength(TextObj)&&pagenum=Ceil(objlength(Rvlk_Array)/6)-1&&pagenum>0){
			pagenum:=0,selectpos:=1
			Gosub split_Page
		}Else{
			selectpos:=selectpos=objlength(TextObj)?1:selectpos+1
			Gosub MatchCandidate
		}
		if WinExist("ahk_id " BttObj.HWND)&&objlength(RvlkObj){
			ZGList:=GetSelectZGList(RvlkObj[3,5],False)
			BttObj:=btt(ZGList, , , 1, BttStyle, {CoordMode:"Screen"})
		}
	Return

	$esc::
	$Delete::
	$BS::
		Critical
		SendInput,{LButton}
		Gosub Empty_value_off
	Return

	$LButton::
		Critical
		MouseGetPos,x,y, id
		if (id=WinExist("ahk_id " RvlkGui)&&WinExist("ahk_id " BttObj.HWND)){
			Clipboard:=TextObj[selectpos,2]
			SendInput, ^{vk56sc02F}
		}
		SendInput,{LButton}
		Gosub Empty_value_off
	Return

	$Pgup::
	$-::
		Critical
		MouseXpos:=RvlkObj[3,3],MouseYpos:=RvlkObj[3,4]
		Gosub lessWait
		if WinExist("ahk_id " BttObj.HWND)&&objlength(RvlkObj){
			ZGList:=GetSelectZGList(RvlkObj[3,5],False)
			BttObj:=btt(ZGList, , , 1, BttStyle, {CoordMode:"Screen"})
		}
	return

	$Pgdn::
	$=::
		Critical
		MouseXpos:=RvlkObj[3,3],MouseYpos:=RvlkObj[3,4]
		Gosub MoreWait
		if WinExist("ahk_id " BttObj.HWND)&&objlength(RvlkObj){
			ZGList:=GetSelectZGList(RvlkObj[3,5],False)
			BttObj:=btt(ZGList, , , 1, BttStyle, {CoordMode:"Screen"})
		}
	return

	$RButton::
		MouseGetPos,,,kid
		if (kid=WinExist("ahk_id " RvlkGui)&&kid){
			Gosub Screenshot_ToolTip
			if DllCall("User32.dll\IsClipboardFormatAvailable","UINT",0x02){  ;0x1 ->ANSI text format.0x0D ->Unicode text format、0x2 ->A handle to a bitmap
				SendInput, ^{vk56sc02F}
				Gosub,Empty_value_off
				CustomTrayTip("截图提示","当前结果已截图发送至剪切板！",1,A_HOUR>5&&A_HOUR<18?false:True)
			}else{
				Gosub,Empty_value_off
				SendInput,{RButton}
			}
		}Else{
			Gosub,Empty_value_off
			SendInput,{RButton}
		}
	Return
#if

WM_MOUSEMOVE( p_w, p_l, p_m, p_hw){
	Global RvlkGui,RvlkObj,FontInfo,BttStyle,BttObj
	if (A_Gui="DTT"&&objlength(RvlkObj)){
		BttStyle:={Font:FontInfo,FontSize:20,Margin:12,Rounded:15, BorderColor:A_HOUR>5&&A_HOUR<18?0xffaabbcc:0xeff0f0f0, TextColor:A_HOUR>5&&A_HOUR<18?0xff112233:0xfff0f0f0, BackgroundColor:A_HOUR>5&&A_HOUR<18?0xe1f0f0f0:0xe13e4143}
		CoordMode,Mouse,Screen
		MouseGetPos, X, Y, 
		if (X>RvlkObj[1,1]+RvlkObj[3,3]&&X<RvlkObj[1,1]+RvlkObj[3,3]+RvlkObj[1,3]&&Y>RvlkObj[1,2]+RvlkObj[3,4]&&Y<RvlkObj[1,2]+RvlkObj[3,4]+RvlkObj[1,4]){
			ZGList:=GetSelectZGList(RvlkObj[3,5],False)
			BttObj:=btt(ZGList, , , 1, BttStyle, {CoordMode:"Screen"})
		}Else if (X>RvlkObj[2,1]+RvlkObj[3,3]&&X<RvlkObj[2,1]+RvlkObj[3,3]+RvlkObj[2,3]&&Y>RvlkObj[2,2]+RvlkObj[3,4]&&Y<RvlkObj[2,2]+RvlkObj[3,4]+RvlkObj[2,4]){
			ZGList:=GetSelectZGList(RvlkObj[3,5],False)
			BttObj:=btt(ZGList, , , 1, BttStyle, {CoordMode:"Screen"})
		}else{
			btt("", , , 1),BttObj:={}
		}
	}
}

GetRvlkFileData(){
	if FileExist(A_ScriptDir "\CharacterData.txt"){
		FileRead,Contents,%A_ScriptDir%\CharacterData.txt
		if Not Contents~="\n[^\x00-\xff\#]\t[^\r\n]+"
			FileRead,Contents,%A_Temp%\MouseSelectedTool\CharacterData.txt
	}Else{
		FileAppend,#反查数据格式：单字+Tab+拆分+Tab+编码+Tab+读音`n#设置显示字体：已安装字体填字体内部名称如：字体`t微软雅黑`n#otf或ttf字体文件请写字体路径如：字体`tD:\XXX.otf`n#如果字体与本程序同目录直接填字体名如：字体`tXXX.otf`n,%A_ScriptDir%\CharacterData.txt,UTF-8
		FileRead,Contents,%A_Temp%\MouseSelectedTool\CharacterData.txt
	}

	Return Trim(RegExReplace(Contents,"(*BSR_ANYCRLF)\R+","`r`n"),"`r`n"),Contents:=""
}

SetMouseRlk:
	Critical
	if CNString:=GetClipCNString(){
		Gosub Empty_value_off
		if ObjLength(Rvlk_Array :=GetMouseRlkData(CNString)){
			Gosub split_Page
		}Else{
			Gosub Empty_value_off
			SendInput,{MButton}
		}
	}Else{
		SendInput,{MButton}
	}
Return

Screenshot_ToolTip:
	Try
	{
		if WinExist("ahk_id " RvlkGui){
			WinGetPos , xpos1, Ypos1, Width1, Height1, ahk_id %RvlkGui%
			if WinExist("ahk_id " BttObj.HWND)&&BttObj.w&&BttObj.h {
				ImagePutClipboard([Min(xpos1+1,BttObj.x),Min(Ypos1+1,BttObj.y),Round(Abs(xpos1+1-BttObj.x)+BttObj.w),Round(BttObj.y+BttObj.h>Ypos1+1+Height1?Abs(ypos1+1-BttObj.y)+BttObj.h:Height1)])
			}Else{
				ImagePutClipboard([xpos1+1,Ypos1+1,Width1-1,Height1])
			}
		}
	}Catch{
		TrayTip,截图提示,当前窗口不支持！,,2
	}
Return

Empty_value_off:
	selectpos:=1,pagenum:=0,Rvlk_Array:=[],TextObj:=[],RvlkObj:=[]
	,MouseXpos:="",MouseYpos:="",btt("",,,1),BttObj:={}
	DllCall("DestroyWindow","ptr",RvlkGui)
	EmptyMem()
return

split_Page:
	TextObj:=[],loopindex:=!Floor(ObjLength(Rvlk_Array)/6)?0:6*PageNum
	Loop,6
	{
		if objlength(Rvlk_Array[loopindex+A_Index]){
			TextObj.Push(Rvlk_Array[loopindex+A_Index])
		}
	}
	Gosub MatchCandidate
Return

;候选下一页
MoreWait:
	If (PageNum*6+6<Rvlk_Array.Length()){
		PageNum+=1,selectpos:=1
		Gosub split_Page
	}
Return

;候选上一页
lessWait:
	If (PageNum>0){
		PageNum-=1,selectpos:=1
		Gosub split_Page
	}
Return

MatchCandidate:
	RegExMatch("`n" RvlkFileData,"i)(?<=\n字体`t).+",FontInfo)
	if (Trim(FontInfo)~="i)\.(otf|ttf)$"){
		if FileExist(A_ScriptDir "\" Trim(FontInfo)){
			FontInfo:=A_ScriptDir "\" Trim(FontInfo)
		}else if FileExist(A_Temp "\MouseSelectedTool\" Trim(FontInfo)){
			FontInfo:=A_Temp "\MouseSelectedTool\" Trim(FontInfo)
		}Else{
			FontInfo:=Trim(FontInfo)
		}
	}
	if (TextObj[selectpos,1]<>""&&TextObj[selectpos,5]=""){
		Index:=1
		While Index:=RegExMatch("`n" RvlkFileData,"i)(?<=\n" TextObj[selectpos,1] "\t)[^\r\n]+",match,Index) {
			if (match="")
				Break
			looptemp:=StrSplit(TextObj[selectpos,1] "`t" Match,"`t"),index+=GetStrLen(match,Array)
			,TextObj[selectpos,2]:=StrLen(looptemp[2])<>StrLen(TextObj[selectpos,2])?Trim(TextObj[selectpos,2] "   " looptemp[2]," "):TextObj[selectpos,2]
			,TextObj[selectpos,3]:=StrLen(looptemp[3])<>StrLen(TextObj[selectpos,3])?Trim(TextObj[selectpos,3] "," looptemp[3],","):TextObj[selectpos,3]
			,TextObj[selectpos,4]:=StrLen(looptemp[4])<>StrLen(TextObj[selectpos,4])?Trim(TextObj[selectpos,4] "·" looptemp[4],"·"):TextObj[selectpos,4]
		}
		TextObj[selectpos,5]:=Format("U+{:X}",Ord(TextObj[selectpos,1]))
		TextObj[selectpos,6]:=CheckCharset(Trim(TextObj[selectpos,1]))
	}
	RvlkObj:=DrawRvlkGui("鼠标右键截图，[Pgdn、=、Pgup、-]翻页或[左右方向键]或[鼠标滚轮上下滑动]进行字符切换显示！",TextObj,FontInfo,MouseXpos,MouseYpos,A_HOUR>5&&A_HOUR<18?false:True)
Return

GetSelectZGList(string,flag:=False){
	Global RvlkFileData
	if flag
		string:=RegExReplace(string,"[^a-zA-Z]")
	if (string="")
		Return
	ZGList:="",tempvar:=""
	if string~="([A-Z][a-z])+"{
		len:=objlength(Array:=StrSplit(Trim(RegExReplace(string,"([A-Z][a-z]|[^A-Za-z])","$1｜"),"｜"),"｜"))
	}Else{
		len:=GetStrLen(string,Array)
	}
	Loop,% len
	{
		if flag {
			if RegExMatch("`n" RvlkFileData,"i)(?<=\n" Trim(Array[A_Index]) "\t)[^\r\n]+",match)&&!InStr(tempvar,Trim(Array[A_Index])){
				ZGList.=RegExReplace(match,"((.){18})","$1`n      ") "`r`n" ,tempvar.=Trim(Array[A_Index])
			}
		}Else{
			if RegExMatch("`n" RvlkFileData,"i)(?<=\n" Trim(Array[A_Index]) "\t)[^\r\n]+",match){  ;&&!InStr(tempvar,Trim(Array[A_Index]))
				ZGList.=RegExReplace(match,"((.){18})","$1`n      ") "`r`n" ;,tempvar.=Trim(Array[A_Index])
			}Else{
				ZGList.= "****************************************`r`n"
			}
		}
	}

	Return Trim(ZGList,"`r`n")
}

;;窗口透明度调节Transparent,不填就是默认的235 微透
DrawRvlkGui(Title,TextObj,Font,Xpos:="",Ypos:="",Dark:=True,Transparent:=235){
	Static DPI:=A_ScreenDPI/96,FontSize:=24,Isbold:=False
	Global CTToken,selectpos,RvlkGui,pagenum,Rvlk_Array
	If (!CTToken){
		CTToken:=Gdip_Startup()
	}
	Gui, DTT: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HWNDRvlkGui ;-DPIScale
	Gui, DTT: Show, NA
	Transparent:=Transparent>255?255:Transparent<0?0:Transparent
	;获取系统默认字体名称
	NumPut(VarSetCapacity(info, A_IsUnicode ? 504 : 344, 0), info, 0, "UInt")
	DllCall("SystemParametersInfo", "UInt", 0x29, "UInt", 0, "Ptr", &info, "UInt", 0)
	SystemFontName:=StrGet(&info + 52)?StrGet(&info + 52):"宋体"
	;设定默认坐标为当前鼠标指针坐标
	if (Xpos=""||Ypos=""){
		static i:=VarSetCapacity(i,8,0)
		DllCall("GetCursorPos","Ptr",&i),Xpos:=NumGet(i,0,"Int"),Ypos:=NumGet(i,4,"Int")
	}
	hbm := CreateDIBSection(1, 1), hdc := CreateCompatibleDC()
	obm := SelectObject(hdc, hbm), G := Gdip_GraphicsFromHDC(hdc)
	CreateRectF(RC, 0, 0, 0, 0),Width:=0,Height:=0
	if FileExist(Font){
		hFontCollection := Gdip_NewPrivateFontCollection()
		hFamily := Gdip_CreateFontFamilyFromFile(Font, hFontCollection)
	}Else hFamily := Gdip_FontFamilyCreate(Font)
	if !(hFamily){
		hFamily := Gdip_FontFamilyCreateGeneric(1)
	}
	DefalutFamily := Gdip_FontFamilyCreate(SystemFontName)
	if !(DefalutFamily){
		DefalutFamily := Gdip_FontFamilyCreateGeneric(1)
	}
	hFont := Gdip_FontCreate(hFamily, FontSize*DPI, Isbold)
	dFont := Gdip_FontCreate(DefalutFamily, FontSize*DPI, Isbold)
	dFont2 := Gdip_FontCreate(DefalutFamily, FontSize, 0)
	dFont3 := Gdip_FontCreate(DefalutFamily, FontSize*0.8, 0)
	FocusFont := Gdip_FontCreate(hFamily, FontSize*2*DPI, Isbold)
	hFormat := Gdip_StringFormatCreate(0x4000)
	If !hFormat
		hFormat := Gdip_StringFormatGetGeneric(1)
	Gdip_SetStringFormatAlign(hFormat, 0), pBrushList := []
	For each,element in {Bg:Dark?"333333":"f0f0f0",Focus:Dark?"f0f0f0":"444444",Font:Dark?"f0f0f0":"333333",FocusFont:Dark?"333333":"f0f0f0",Comment:Dark?"17ffff":"E81010"}
	{
		If (!pBrushList[each])
			pBrushList[each] := Gdip_BrushCreateSolid("0x" . (each="bg"?Format("{:02x}",Transparent):"FF") . element)
	}
	;线条颜色
	pPen_line := Gdip_CreatePen("0xff" (Dark?"f0f0f0":"444444"), 1)
	hbm := CreateDIBSection(1, 1), hdc := CreateCompatibleDC(), obm := SelectObject(hdc, hbm)
	G := Gdip_GraphicsFromHDC(hdc),TempW:=0
	;获取标题说明文字大小
	TempRC1:=StrSplit(Gdip_MeasureString(G, "拆分字根：", dFont, hFormat, RC), "|")
	;获取选择项大小
	TempRC2:=StrSplit(Gdip_MeasureString(G, TextObj[selectpos,1], FocusFont, hFormat, RC), "|")
	Loop,% objlength(TextObj[selectpos])
	{
		if (A_Index>1){
			loopRC :=StrSplit(Gdip_MeasureString(G, TextObj[selectpos,A_Index], hFont, hFormat, RC),"|")
			Width:=Max(TempRC2[3]+TempRC1[3]+80,TempRC1[3]+loopRC[3]+15,TempW),TempW:=Width
		}
	}
	Width:=Max(Round(Width),TempRC2[3]+TempRC1[3]+80),Height:=Round((TempRC1[4]+15)*5.85+TempRC2[4]*1.35)
	SelectObject(hdc, obm), DeleteObject(hbm), Gdip_DeleteGraphics(G)
	hbm := CreateDIBSection(Width+8, Height+8), obm := SelectObject(hdc, hbm)
	G := Gdip_GraphicsFromHDC(hdc), Gdip_SetSmoothingMode(G, 2), Gdip_SetTextRenderingHint(G, 4)
	;绘背景色
	Gdip_FillRoundedRectangle(G, pBrushList["Bg"], 0, 0, Width+8, Height+8, 0),loopXpos:=4,loopYpos:=4
	;绘边框线条
	;Gdip_DrawRoundedRectangle(G, pPen_Line, 0, 0, Width+6, Height+6, 0)
	Gdip_DrawRoundedRectangle(G, pPen_Line, 4, 4, Width-2, Height-2, 0)
	Loop,% objlength(TextObj){
		if (selectpos=A_Index){
			Gdip_FillRoundedRectangle(G,pBrushList["Focus"], loopXpos, 4, A_Index<>6?TempRC2[3]:TempRC2[3]-2, TempRC2[4], 0)
			FouceRC:=StrSplit(Gdip_TextToGraphics(G, TextObj[A_Index,1], "x" loopXpos " y" (DPI<=1.25?Abs(TempRC2[4]-TempRC2[3])+Round(FontSize/10)+4:Round(TempRC1[4]/4)+4) " cff" (!Dark?"ffffff":"000000") " s" FontSize*2*DPI " bold", Font, TempRC2[3], TempRC2[4]),"|")
			,loopXpos+=TempRC2[3]
			if (A_Index=1){
				Gdip_DrawLine(G, pPen_Line, TempRC2[3], TempRC2[4]-TempRC1[4]+3, Width, TempRC2[4]-TempRC1[4]+3)
				Gdip_DrawLine(G, pPen_Line, TempRC2[3], TempRC2[4]+3, Width, TempRC2[4]+3)
			}Else if (A_Index=objlength(TextObj)){
				Gdip_DrawLine(G, pPen_Line, 4, TempRC2[4]-TempRC1[4]+3, Width-TempRC2[3]-(6-objlength(TextObj))*(Width-TempRC2[3])/5+4, TempRC2[4]-TempRC1[4]+3)
				Gdip_DrawLine(G, pPen_Line, 4, TempRC2[4]+3, Width-TempRC2[3]-(6-objlength(TextObj))*(Width-TempRC2[3])/5+4, TempRC2[4]+3)
				if (6-objlength(TextObj)){
					Gdip_DrawLine(G, pPen_Line, FouceRC[1]+FouceRC[3], TempRC2[4]-TempRC1[4]+3, Width, TempRC2[4]-TempRC1[4]+3)
					Gdip_DrawLine(G, pPen_Line, FouceRC[1]+FouceRC[3], TempRC2[4]+3, Width, TempRC2[4]+3)
				}
			}Else{
				Gdip_DrawLine(G, pPen_Line, 4, TempRC2[4]-TempRC1[4]+3, FouceRC[1], TempRC2[4]-TempRC1[4]+3)
				Gdip_DrawLine(G, pPen_Line, FouceRC[1]+FouceRC[3], TempRC2[4]-TempRC1[4]+3, Width, TempRC2[4]-TempRC1[4]+3)
				Gdip_DrawLine(G, pPen_Line, 4, TempRC2[4]+3, FouceRC[1], TempRC2[4]+3)
				Gdip_DrawLine(G, pPen_Line, FouceRC[1]+FouceRC[3], TempRC2[4]+3, Width, TempRC2[4]+3)
			}
		}Else{
			CreateRectF(RC, loopXpos, TempRC2[4]-TempRC1[4], (Width-TempRC2[3])/5, TempRC1[4])
			Gdip_TextToGraphics(G, TextObj[A_Index,1], "x" loopXpos+((Width-TempRC2[3])/5-TempRC1[3]/5)/2-4 " y" (TempRC2[4]-TempRC1[4]+(Round(FontSize*DPI/10)+4)+4) " cff" (Dark?"ffffff":"000000") " s" FontSize*DPI , Font, (Width-TempRC2[3])/5, TempRC1[4])
			,loopXpos+=(Width-TempRC2[3])/5
			if (A_Index<>6)
				Gdip_DrawLine(G, pPen_Line, loopXpos, TempRC2[4]-TempRC1[4]+4, loopXpos, TempRC2[4]+4)
		}
	}
	;;拆分显示行
	CreateRectF(RC, 4, TempRC2[4]+15, TempRC1[3], TempRC1[4]),Gdip_DrawString(G, "码元拆分：", dFont2, hFormat, pBrushList["Font"], RC)
	CreateRectF(RC, TempRC1[3]/DPI, TempRC2[4]+15, Width, TempRC1[4]),Gdip_DrawString(G, TextObj[selectpos,2], hFont, hFormat, pBrushList["Comment"], RC)
	Gdip_DrawLine(G, pPen_Line, 4, TempRC2[4]+15+TempRC1[4], Width+1, TempRC2[4]+15+TempRC1[4])
	;;编码显示行
	CreateRectF(RC, 4, TempRC2[4]+15+(TempRC1[4]+15)*1, TempRC1[3], TempRC1[4]),Gdip_DrawString(G, "反查编码：", dFont2, hFormat, pBrushList["Font"], RC)
	CreateRectF(RC, TempRC1[3]/DPI, TempRC2[4]+15+(TempRC1[4]+15)*1, Width, TempRC1[4]),Gdip_DrawString(G, TextObj[selectpos,3], hFont, hFormat, pBrushList["Comment"], RC)
	Gdip_DrawLine(G, pPen_Line, 4, TempRC2[4]+15+TempRC1[4]+(TempRC1[4]+15)*1, Width+1, TempRC2[4]+15+TempRC1[4]+(TempRC1[4]+15)*1)
	;;拼音显示行
	CreateRectF(RC, 4, TempRC2[4]+15+(TempRC1[4]+15)*2, TempRC1[3], TempRC1[4]),Gdip_DrawString(G, "反查拼音：", dFont2, hFormat, pBrushList["Font"], RC)
	CreateRectF(RC, TempRC1[3]/DPI, TempRC2[4]+15+(TempRC1[4]+15)*2, Width, TempRC1[4]),Gdip_DrawString(G, TextObj[selectpos,4], dFont2, hFormat, pBrushList["Comment"], RC)
	Gdip_DrawLine(G, pPen_Line, 4, TempRC2[4]+15+TempRC1[4]+(TempRC1[4]+15)*2, Width+1, TempRC2[4]+15+TempRC1[4]+(TempRC1[4]+15)*2)
	;;统一码显示行
	CreateRectF(RC, 4, TempRC2[4]+15+(TempRC1[4]+15)*3, TempRC1[3], TempRC1[4]),Gdip_DrawString(G, "统一码：", dFont2, hFormat, pBrushList["Font"], RC)
	CreateRectF(RC, TempRC1[3]/DPI, TempRC2[4]+15+(TempRC1[4]+15)*3+TempRC1[4]*0.1, Width, TempRC1[4]),Gdip_DrawString(G, TextObj[selectpos,5], dFont2, hFormat, pBrushList["Comment"], RC)
	Gdip_DrawLine(G, pPen_Line, 4, TempRC2[4]+15+TempRC1[4]+(TempRC1[4]+15)*3, Width+1, TempRC2[4]+15+TempRC1[4]+(TempRC1[4]+15)*3)
	;;统一码范围
	CreateRectF(RC, 4, TempRC2[4]+15+(TempRC1[4]+15)*4, TempRC1[3], TempRC1[4]),Gdip_DrawString(G, "字符范围：", dFont2, hFormat, pBrushList["Font"], RC)
	CreateRectF(RC, TempRC1[3]/DPI, InStr(TextObj[selectpos,6],"`n")?TempRC2[4]+15+TempRC1[4]+(TempRC1[4]+15)*3+3:TempRC2[4]+15+(TempRC1[4]+15)*4+TempRC1[4]*0.1, Width, TempRC1[4]),Gdip_DrawString(G, TextObj[selectpos,6], InStr(TextObj[selectpos,6],"`n")?dFont3:dFont2, hFormat, pBrushList["Comment"], RC)
	Gdip_DrawLine(G, pPen_Line, 4, TempRC2[4]+15+TempRC1[4]+(TempRC1[4]+15)*4, Width+1, TempRC2[4]+15+TempRC1[4]+(TempRC1[4]+15)*4)
	;;提示文字显示行
	Gdip_TextToGraphics(G, Title, "x6 y" TempRC2[4]+15+TempRC1[4]+(TempRC1[4]+15)*4+3 " cff" (Dark?"17ffff":"E81010") " s" FontSize*0.75 , SystemFontName, Width-8, TempRC1[4]*1.35)
	
	UpdateLayeredWindow(RvlkGui, hdc, Xpos:=Xpos+Width+8>A_ScreenWidth?A_ScreenWidth-Width-8:Xpos, Ypos:=Ypos+Height+8>A_ScreenHeight?A_ScreenHeight-Height-8:Ypos, Width+8, Height+8), Gdip_DeleteFont(FocusFont)
	SelectObject(hdc, obm), DeleteObject(hbm), DeleteDC(hdc), Gdip_DeleteGraphics(G), Gdip_DeleteFontFamily(DefalutFamily), Gdip_DeleteFont(dFont2), Gdip_DeleteFont(dFont3)
	Gdip_DeleteStringFormat(hFormat), Gdip_DeleteFont(hFont), Gdip_DeleteFont(dFont), Gdip_DeleteFontFamily(hFamily)
	Gdip_DeletePen(pPen_Line)
	For key,value in pBrushList
		Gdip_DeleteBrush(value)

	Return WinExist("ahk_id " RvlkGui)?[[TempRC1[3]/DPI, TempRC2[4]+15, Width+8, TempRC1[4]],[TempRC1[3]/DPI, TempRC2[4]+15+(TempRC1[4]+15)*1, Width+8, TempRC1[4]],[Width+8,Height+8,Xpos,Ypos,TextObj[selectpos,3]]]:[]
}

Unicode2Ansi(ByRef wString, ByRef sString, CP = 0){
	nSize := DllCall("WideCharToMultiByte", "Uint", CP, "Uint", 0, "Uint", &wString, "int",  -1, "Uint", 0, "int", 0, "Uint", 0, "Uint", 0) 
	VarSetCapacity(sString, nSize)
	DllCall("WideCharToMultiByte", "Uint", CP, "Uint", 0, "Uint", &wString, "int",  -1, "str",  sString, "int",  nSize, "Uint", 0, "Uint", 0)
}

/*
	多个字符时只判断第一个字
	full
		True：显示完整判断，False：简略显示
*/
;;GB2312半角标点符号及特殊符号	\xa1[\xa2-\xfe]
;;GB2312罗马数组及项目序号	\xa2([\xa1-\xaa]|[\xb1-\xbf]|[\xc0-\xdf]|[\xe0-\xe2]|[\xe5-\xee]|[\xf1-\xfc])
;;GB2312全角标点及全角字母	\xa3[\xa1-\xfe]
;;GB2312日文平假名	\xa4[\xa1-\xf3]
;;GB2312日文片假名	\xa5[\xa1-\xf6]
CheckCharset(String,full:=False){
	String:=Chr(Ord(String)),VarSetCapacity(str,StrPut(String, "CP936")*4),StrPut(String,&str, "CP936")
	L1:=Format("0x{:X}",NumGet(&str,0,"UChar")),L2:=Format("0x{:X}",NumGet(&str,1,"UChar"))
	if String~="^[\x{4E00}-\x{9FFF}]$"{
		if (L1 < 0xB0 || L2 < 0xA1 || L1 > 0xF7 || L2 = 0xFF){
			if String~="^[\x{4E00}-\x{9FA5}]$"{
				Return full?"GBK、GB18030-2000`nCJK基本汉字、GB18030-2005":"GBK`nCJK基本汉字"
			}Else if String~="^[\x{9FA6}-\x{9FFF}]$"{
				Return full?"GBK、GB18030-2000`nCJK基本汉字补充、GB18030-2005":"GBK`nCJK基本汉字补充"
			}
		}Else{
			if String~="^[\x{4E00}-\x{9FA5}]$"{
				Return full?"GB2312、GB18030-2000`nCJK基本汉字、GB18030-2005":"GB2312`nCJK基本汉字"
			}Else if String~="^[\x{9FA6}-\x{9FFF}]$"{
				Return full?"GB2312、GB18030-2000`nCJK基本汉字补充、GB18030-2005":"GB2312`nCJK基本汉字补充"
			}
		}
	}Else if String~="^[\x{3400}-\x{4DBF}]$"{  ; 扩展A
		if (L1 < 0xB0&&L1 || L2 < 0xA1&&L2 || L1 > 0xF7&&L1 || L2 = 0xFF&&L2)
			Return "扩展A`nGB18030-2000"
		Else
			Return "扩展A"
	}Else if String~="^[\x{20000}-\x{2A6DF}]$"{  ; 扩展B
		if (L1 < 0xB0&&L1 || L2 < 0xA1&&L2 || L1 > 0xF7&&L1 || L2 = 0xFF&&L2)
			Return "扩展B`nGB18030-2005"
		Else
			Return "扩展B"
	}Else if String~="^[\x{2A700}-\x{2B73F}]$"{  ; 扩展C
		Return "扩展C"
	}Else if String~="^[\x{2B740}-\x{2B81F}]$"{  ; 扩展D
		Return "扩展D"
	}Else if String~="^[\x{2B820}-\x{2CEAF}]$"{  ; 扩展E
		Return "扩展E"
	}Else if String~="^[\x{2CEB0}-\x{2EBEF}]$"{  ; 扩展F
		Return "扩展F"
	}Else if String~="^[\x{30000}-\x{3134A}]$"{  ; 扩展G
		Return "扩展G"
	}Else if String~="^[\x{3007}]$"{  ; 〇
		Return "〇"
	}Else if String~="^[\x{2F00}-\x{2FD5}]$"{
		Return "康熙部首"
	}Else if String~="^[\x{2E80}-\x{2EF3}]$"{
		Return "部首扩展"
	}Else if String~="^[\x{F900}-\x{FAD9}]$"{
		Return "CJK兼容汉字"
	}Else if String~="^[\x{2F800}-\x{2FA1D}]$"{
		Return "CJK兼容扩展"
	}Else if String~="^[\x{E815}-\x{E86F}]$"{
		Return "PUA(GBK)部件"
	}Else if String~="^[\x{E400}-\x{E5E8}]$"{
		Return "部件扩展"
	}Else if String~="^[\x{E600}-\x{E6CF}]$"{
		Return "PUA增补"
	}Else if chars~="^[\x{31C0}-\x{31E3}]$"{
		Return "汉字笔画"
	}Else if String~="^[\x{2FF0}-\x{2FFB}]$"{
		Return "汉字结构"
	}Else if String~="^[\x{3105}-\x{312F}]$"{
		Return "汉语注音"
	}Else if String~="^[\x{31A0}-\x{31BA}]$"{
		Return "注音扩展"
	}Else if String~="^[\x00-\xff]$"{
		Return "非中文"
	}
}

;;判断字符串中文Unicode字集
CheckUnicode(chars){
	if chars~="^[\x{4E00}-\x{9FA5}]$"{
		Return "CJK基本汉字"
	}Else if chars~="^[\x{9FA6}-\x{9FFF}]$"{  ;0x4E00-0x9FFF
		Return "CJK基本汉字补充"
	}Else if chars~="^[\x{3400}-\x{4DBF}]$"{  ;0x3400-0x4DBF
		Return "扩展A"
	}Else if chars~="^[\x{20000}-\x{2A6DF}]$"{  ;0x20000-0x2A6DF 
		Return "扩展B"
	}Else if chars~="^[\x{2A700}-\x{2B73F}]$"{  ;0x2A700-0x2B73F
		Return "扩展C"
	}Else if chars~="^[\x{2B740}-\x{2B81F}]$"{  ;0x2B740-0x2B81F 
		Return "扩展D"
	}Else if chars~="^[\x{2B820}-\x{2CEAF}]$"{  ;0x2B820-0x2CEAF 
		Return "扩展E"
	}Else if chars~="^[\x{2CEB0}-\x{2EBEF}]$"{  ;0x2CEB0-0x2EBEF
		Return "扩展F"
	}Else if chars~="^[\x{30000}-\x{3134A}]$"{
		Return "扩展G"
	}Else if chars~="^[\x{2F00}-\x{2FD5}]$"{
		Return "康熙部首"
	}Else if chars~="^[\x{2E80}-\x{2EF3}]$"{
		Return "部首扩展"
	}Else if chars~="^[\x{F900}-\x{FAD9}]$"{
		Return "CJK兼容汉字"
	}Else if chars~="^[\x{2F800}-\x{2FA1D}]$"{
		Return "CJK兼容扩展"
	}Else if chars~="^[\x{E815}-\x{E86F}]$"{
		Return "PUA(GBK)部件"
	}Else if chars~="^[\x{E400}-\x{E5E8}]$"{
		Return "部件扩展"
	}Else if chars~="^[\x{E600}-\x{E6CF}]$"{
		Return "PUA增补"
	}Else if chars~="^[\x{31C0}-\x{31E3}]$"{
		Return "汉字笔画"
	}Else if chars~="^[\x{2FF0}-\x{2FFB}]$"{
		Return "汉字结构"
	}Else if chars~="^[\x{3105}-\x{312F}]$"{
		Return "汉语注音"
	}Else if chars~="^[\x{31A0}-\x{31BA}]$"{
		Return "注音扩展"
	}Else if chars~="^[\x{3007}]$"{
		Return "〇"
	}Else{
		Return ""
	}
}

EmptyMemoryTimer:
	;鼠标键盘15分钟无操作自动重载
	if (A_TimeIdlePhysical>900000){
		Reload
	}
Return

OnAbout:
	BrowserPath:=GetDefaultBrowserPath()
	Run,%BrowserPath% "http://98wb.ysepan.com/",, UseErrorLevel
	if (ErrorLevel="Error"){
		Run,msedge.exe "http://98wb.ysepan.com/",,Useerrorlevel
		if (ErrorLevel="Error"){
			Run,iexplore.exe "http://98wb.ysepan.com/",,Useerrorlevel
		}
	}
Return

OnExits:
	EmptyMem()
	ExitApp
Return

OnReload:
	Reload
Return

RegReadFunc(RootKey, SubKey,ValueName=""){
	if (A_Is64bitOS&&A_PtrSize>4){
		SetRegView, 64
	}
	RegRead, Var, %RootKey%\%SubKey%, %ValueName%

	Return Var
}

;;获取默认浏览器路径
GetDefaultBrowserPath(){
	RegRead,item1,HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice,ProgId
	RegRead,item2,HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice,ProgId
	if item1 {
		RegRead,item,HKEY_LOCAL_MACHINE\SOFTWARE\Classes\%item1%\shell\open\command
		RegExMatch(item,"i)([a-zA-Z]\:\\.+\.exe)",BrowserPath)
	}
	if FileExist(Trim(BrowserPath)){
		Return Trim(BrowserPath)
	}Else{
		if item2 {
			RegRead,item,HKEY_LOCAL_MACHINE\SOFTWARE\Classes\%item2%\shell\open\command
			RegExMatch(item,"i)([a-zA-Z]\:\\.+\.exe)",BrowserPath)
			if FileExist(Trim(BrowserPath))
				Return Trim(BrowserPath)
			Else{
				RegRead, BrowserPath, HKLM, SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\iexplore.exe
				Return Trim(BrowserPath)
			}
		}Else{
			RegRead, BrowserPath, HKLM, SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\iexplore.exe
			Return Trim(BrowserPath)
		}
	}
}

GetMouseRlkData(string){
	Global RvlkFileData,selectpos,pagenum
	obj:=[]
	loop,% GetStrLen(string,Array)
	{
		obj[A_Index]:=[Array[A_Index]]
	}

	Return obj
}

GetClipCNString(){
	BlockInput,On
	lastClip:=Clipboard
	Clipboard:=""
	SendInput, ^{vk43sc02E}
	BlockInput,Off
	ClipWait,0.1
	if (Clipboard=="")
		Return
	string:=RegExReplace(Clipboard,"[^\x{4E00}-\x{9FFF}\x{3400}-\x{4DBF}\x{20000}-\x{2A6DF}\x{2A700}-\x{2B73F}\x{2B740}-\x{2B81F}\x{2B820}-\x{2CEAF}\x{2CEB0}-\x{2EBEF}\x{30000}-\x{3134F}\x{2F00}-\x{2FD5}\x{2E80}-\x{2EF3}\x{F900}-\x{FAFF}\x{2F800}-\x{2FA1F}\x{E815}-\x{E86F}\x{E400}-\x{E5E8}\x{E600}-\x{E6CF}\x{31C0}-\x{31E3}\x{2FF0}-\x{2FFB}\x{3105}-\x{312F}\x{31A0}-\x{31BA}\x{3007}\x{E900}-\x{EAD9}]|[\s\t\r\n]+")
	Clipboard:=lastClip
	if !ErrorLevel&&string
		Return chars:=string
}

GetFontslist(){
	static fontlist
	fontlist:=""
	If (fontlist)
		Return fontlist
	VarSetCapacity(logfont, 128, 0), NumPut(1, logfont, 23, "UChar")
	obj := []
	DllCall("EnumFontFamiliesEx", "ptr", DllCall("GetDC", "ptr", 0), "ptr", &logfont, "ptr", RegisterCallback("EnumFontProc"), "ptr", &obj, "uint", 0)
	For font in obj
		fontlist .= "|" font
	fontlist:=LTrim(fontlist,"|")
	Return fontlist
}
EnumFontProc(lpFont, tm, TextFont, lParam){
	obj := Object(lParam)
	If (TextFont>1&&!InStr(font:=StrGet(lpFont+28), "@"))
		obj[font] := 1
	Return 1
}

;;获取字符串个数，返回长度和切割成的数组obj
GetStrLen(str,ByRef obj:="") {
	Static Count:=0
	str:=RegExReplace(str,"[\s\t\r\n]")
	obj:=StrSplit(RTrim(RegExReplace(str,"O)(.)","$1☯☯☯",Count),"☯☯☯"),"☯☯☯")
	Return Count
}

EmptyMem(PID=""){
	pid:=!PID ? DllCall("GetCurrentProcessId") : pid
	h:=DllCall("OpenProcess", "UInt", 0x001F0FFF, "Int", 0, "Int", pid)
	DllCall("SetProcessWorkingSetSize", "UInt", h, "Int", -1, "Int", -1)
	DllCall("CloseHandle", "Int", h)
}

;;;================================================================================================
/*
	仿win10 TrayTip通知，可用在win7或托盘图标隐藏的脚本上！
	title：标题
	text：内容
	Mode：1消息,2警告,3错误
	Dark：true深色模式,False浅色模式
	Transparent：透明度[0-255]，0透明，255不透明
	Timeout：显示时长

*/
CustomTrayTip(title,text:="",Mode=1,Dark:=True,Transparent:=225,Timeout:=3500){
	;;Critical
	Global CTToken,hCTT,CTTimer
	Static Index
	if (title=""&&text=""){
		Return
	}
	Gosub FormatString
	TitleFntSize:=22,TextFntSize:=20,Transparent:=Transparent>255?255:Transparent<0?0:Transparent
	NumPut(VarSetCapacity(info, A_IsUnicode ? 504 : 344, 0), info, 0, "UInt")
	DllCall("SystemParametersInfo", "UInt", 0x29, "UInt", 0, "Ptr", &info, "UInt", 0)
	SystemFontName:=StrGet(&info + 52)?StrGet(&info + 52):"宋体"
	if !DllCall("GetModuleHandle", "str", "gdiplus", "UPtr")
		DllCall("LoadLibrary", "str", "gdiplus")
	VarSetCapacity(si, A_PtrSize = 8 ? 24 : 16, 0), si := Chr(1)
	DllCall("gdiplus\GdiplusStartup", "UPtr*", CTToken, "UPtr", &si, "UPtr", 0)
	If !CTToken
	{
		MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
		ExitApp
	}
	Gui, TT: -Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs +HWNDhCTT -DPIScale
	Gui, TT: Show, NA
	VarSetCapacity(bi, 40, 0),NumPut(40, bi, 0, "uint"),NumPut(1, bi, 4, "uint")
	NumPut(1, bi, 8, "uint"),NumPut(1, bi, 12, "ushort"),NumPut(32, bi, 14, "ushort"),NumPut(0, bi, 16, "uInt")
	hbm := DllCall("CreateDIBSection", "UPtr", DllCall("GetDC", "UPtr", 0), "UPtr", &bi, "uint", 0, "UPtr*", 0, "UPtr", 0, "uint", 0, "UPtr")
	hdc := DllCall("CreateCompatibleDC", "UPtr", 0)
	obm := DllCall("SelectObject", "UPtr", hdc, "UPtr", hbm), DllCall("gdiplus\GdipCreateFromHDC", "UPtr", hdc, "UPtr*", G)
	DllCall("gdiplus\GdipCreateFontFamilyFromName", "WStr", SystemFontName, "uint", 0, "UPtr*", hFamily)
	If !hFamily
		DllCall("gdiplus\GdipGetGenericFontFamilySansSerif", "UPtr*", hFamily)
	DllCall("gdiplus\GdipCreateFont", "UPtr", hFamily, "float", TitleFntSize, "int", text=""&&title<>""?0:1, "int", 0, "UPtr*", tFont)
	DllCall("gdiplus\GdipCreateFont", "UPtr", hFamily, "float", TextFntSize, "int", 0, "int", 0, "UPtr*", hFont)
	DllCall("gdiplus\GdipStringFormatGetGenericDefault", "UPtr*", tFormat)
	DllCall("gdiplus\GdipStringFormatGetGenericDefault", "UPtr*", hFormat)
	VarSetCapacity(TempRC, 16)
	DllCall("gdiplus\GdipMeasureString", "UPtr", G, "WStr", title, "int", -1, "UPtr"
		, tFont, "UPtr", &RC, "UPtr", hStringFormat, "UPtr", &TempRC, "uint*", 0, "uint*", 0)
	TitleRC:=[NumGet(TempRC, 0, "float"),NumGet(TempRC, 4, "float"),NumGet(TempRC, 8, "float"),NumGet(TempRC, 12, "float")]
	VarSetCapacity(TempRC, 16)
	DllCall("gdiplus\GdipMeasureString", "UPtr", G, "WStr", Text, "int", -1, "UPtr"
		, hFont, "UPtr", &RC, "UPtr", hStringFormat, "UPtr", &TempRC, "uint*", 0, "uint*", 0)
	TextRC:=[NumGet(TempRC, 0, "float"),NumGet(TempRC, 4, "float"),NumGet(TempRC, 8, "float"),NumGet(TempRC, 12, "float")]
	base64_1=
	(join`r`n LTrim
	iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAABMVJREFUeF7tm02IHEUUx/+vdyN+BrZHo
	h4Mxp3uJQGPJnrQQ7KKB00O4kEURPBjtyYnAyqKHhTFCHrK1q4fIIKoJyGJAdHVgx408ZiD7PRsIuZgEu1e8DPETT/puGN2Z7qnq7urqxtmF/qy86rqvd+8e
	l0f/yEM+R8NefxYB7CeAQYIjMmFOwDrHgI2RQ8zXwdg08oTeXA2eojoDANnowcIP1sSE9+U7V5pU6Axt7gLzHcz84MAbswZyCki+ghEn/tT41/m7GNgM60Ar
	jnwQ2MDjQiQ9TDArl6HqQ0OP/iHL8jf9271dfWtBcBN7528/Le/lwURBDPGdTkX1w8RFpkhN14xKn98dMu5omMVBjAm21PEJEC4pagzmdozjjOxXBLuXKZ2P
	caFANiy/RZATxRxoHhbfjsQ7pN5+8kNwJadLwCezDuw3nY0H4jmXXn6zAXAlt4igJvzDFhimxOBcDLXn8wAbOlxiUEU7joQTqaYMhnbsnMM4FsLe1lqB/R9I
	JrbVYdQBtCY9WaYIVQ7rtKOCNKfdloqPigBaMj2awx6RqXDutgQeL8v3GfT/EkFcPE9D5pN6yjr571ztYzawuDptHXCQAAXV3h/LR8rY5FjAgAYxzdeObp90
	IpxIABbek8BeCPrt6tibwTAf47sC4TzZpJPiQCijc1lI6NHy1rbmwIQ7R3OX1jekbSBSgRgz7RfANFLKt9m7W2YXwxa7stxfiYCaEivwyh3Z2cKHAGLvnCay
	gCuld7uEDhoykET41jAnl+Fc6h3rNgMsKX3DoDHTDhmcIx3A+E8rgrgZwDXl+cczQN0ZMTCkV+mxr1onDLWAT3+nw6Ec0MqgMaBhV1sWfNagyc6A+bDFIYf+
	3snYs/2DAAAheFk7/h9U2BMeq8Q8JwuAKq7MxMAGHh1STjPr46tD4Du+U9s3e+3xj9JA2oCAIC+OtAHoCG9gwzsTnNY9XMCf+gL96HV9vacd3sw5Xy75n8Gz
	hkIOOQLZ8/gDJhpfweiHaoBKtidO7+MzRtG8AAR7wTRVjC2mVoJrvGP+WjQcm9LA3ACRFsUAitkUhGAk0HLXXOU118DZtp/gOiqQtEpNK4IwJ9By706LQOGH
	sDQTwHdRTB2QlQ0BdKLoO7XYFI5qAKA2mvQ0EaoCgBKCyHdS+E6ZYDSUjhScxCsrxXeZIVMqsgARnhnr+ok6TzgpwKqDiUwFQA4FQhnc+p2ODJozHb2M/PTS
	pHkNDINgIhe96ebfZc7sRkQ6Xs4DPWeCfSAMg7AsibjdEbJp8Kys6Bf53OJglkA1A5EcyIuWSs7FjcKIM+xuK6LEdUToaRSUvSgJPfFSOSQjquxqgHkvhqLA
	Oi4HK0UQNHL0QhC0evxKgEUvh7vzst6yOGyLjjU5HOpAolLEOoki0uDoS6bUwawUhTrKI/rpZFJLpcJwAqE4ZXJrZoONZTLZZPHdWPJnAHdhnWSzWWRxSntB
	tNKzP8QaiCfU5XDJcWUOwO6HQ61XL4LYah/MLE6tbo/mSGiR3TriyKdDzO/X8ufzMTNrxWd0X0A7i2gNjkN4FMLOByn71GtVYPsCtcAFSci1UloWTuz/GzOC
	sOvktQkKmOq2hgBoOpMFXbrAKqgXqcxhz4D/gVkGDdfoNgmzwAAAABJRU5ErkJggg==
	)
	base64_2=
	(join`r`n LTrim
	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
	)
	base64_3=
	(join`r`n LTrim
	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
	)
	Base64:=Mode=3?base64_3:Mode=2?base64_2:base64_1
	DllCall("crypt32\CryptStringToBinary", "UPtr", &Base64, "UInt", 0, "UInt", 0x01, "UPtr", 0, "UIntP", DecLen, "UPtr", 0, "UPtr", 0)
	VarSetCapacity(Dec, DecLen, 0)
	DllCall("crypt32\CryptStringToBinary", "UPtr", &Base64, "UInt", 0, "UInt", 0x01, "UPtr", &Dec, "UIntP", DecLen, "UPtr", 0, "UPtr", 0)
	DllCall("gdiplus\GdipCreateBitmapFromStreamICM", "UPtr", DllCall("shlwapi\SHCreateMemStream", "UPtr", &Dec, "UInt", DecLen, "UPtr"), "PtrP", pBitmap)
	;;78感叹号，155问号，110
	;;pBitmap := Gdip_CreateBitmapFromFile("shell32.dll" ,Mode=3?110:Mode=2?78:278,40)
	DllCall("gdiplus\GdipGetImageWidth", "UPtr", pBitmap, "uint*", ImageWidth)
	DllCall("gdiplus\GdipGetImageHeight", "UPtr", pBitmap, "uint*", ImageHeight)
	Width := Max(Width:=320,ImageWidth+Max(TitleRC[3]+15,TextRC[3]+15)+40), Height := Max(Height:=120,Max(ImageHeight+50,TitleRC[4]+TextRC[4]+50))
	VarSetCapacity(bi, 40, 0),NumPut(40, bi, 0, "uint"),NumPut(Width, bi, 4, "uint")
	NumPut(Height, bi, 8, "uint"),NumPut(1, bi, 12, "ushort"),NumPut(32, bi, 14, "ushort"),NumPut(0, bi, 16, "uInt")
	hbm := DllCall("CreateDIBSection", "UPtr", DllCall("GetDC", "UPtr", 0), "UPtr", &bi, "uint", 0, "UPtr*", 0, "UPtr", 0, "uint", 0, "UPtr")
	hdc := DllCall("CreateCompatibleDC", "UPtr", 0)
	obm := DllCall("SelectObject", "UPtr", hdc, "UPtr", hbm)
	DllCall("Gdiplus\GdipCreateFromHDC2", "UPtr", hDC, "UPtr", "", "UPtr*", G)
	DllCall("gdiplus\GdipSetSmoothingMode", "UPtr", G, "int", 2)
	;绘背景色
	DllCall("gdiplus\GdipCreateSolidFill", "UInt", "0x" Format("{:02x}",Transparent) (Dark?"000000":"f0f0f0"), "UPtr*", pBrush)
	DllCall("gdiplus\GdipCreateRegion", "UInt*", Region)
	DllCall("gdiplus\GdipGetClip", "UPtr", G, "UInt", Region)
	DllCall("gdiplus\GdipSetClipRect", "UPtr", G, "float", 0, "float", 0, "float", 0, "float", 0, "int", 4)
	DllCall("gdiplus\GdipSetClipRect", "UPtr", G, "float", Width, "float", 0, "float", 0, "float", 0, "int", 4)
	DllCall("gdiplus\GdipSetClipRect", "UPtr", G, "float", 0, "float", Height, "float", 0, "float", 0, "int", 4)
	DllCall("gdiplus\GdipSetClipRect", "UPtr", G, "float", Width, "float", Height, "float", 0, "float", 0, "int", 4)
	DllCall("gdiplus\GdipFillRectangle", "UPtr", G, "UPtr", pBrush, "float", 0, "float", 0, "float", Width, "float", Height)
	DllCall("gdiplus\GdipSetClipRegion", "UPtr", G, "UPtr", Region, "int", 0)
	DllCall("gdiplus\GdipSetClipRect", "UPtr", G, "float", 0, "float", 0, "float", Width, "float", Height, "int", 4)
	DllCall("gdiplus\GdipSetClipRect", "UPtr", G, "float", 0, "float", 0, "float", Width, "float", Height, "int", 4)
	DllCall("gdiplus\GdipFillEllipse", "UPtr", G, "UPtr", pBrush, "float", 0, "float", 0, "float", 0, "float", 0)
	DllCall("gdiplus\GdipFillEllipse", "UPtr", G, "UPtr", pBrush, "float", Width, "float", 0, "float", 0, "float", 0)
	DllCall("gdiplus\GdipFillEllipse", "UPtr", G, "UPtr", pBrush, "float", 0, "float", Height, "float", 0, "float", 0)
	DllCall("gdiplus\GdipFillEllipse", "UPtr", G, "UPtr", pBrush, "float", Width, "float", Height, "float", 0, "float", 0)
	DllCall("gdiplus\GdipSetClipRegion", "UPtr", G, "UPtr", Region, "int", 0)
	DllCall("gdiplus\GdipDeleteRegion", "UPtr", Region)
	DllCall("gdiplus\GdipGetImageDimension", "UPtr", pBitmap, "float*", ImageWidth:=Width, "float*", ImageHeight:=Height)
	ImageWidth := Round(ImageWidth),ImageHeight := Round(ImageHeight)
	DllCall("gdiplus\GdipDrawImageRectRect", "UPtr", G, "UPtr", pBitmap, "float", 15, "float", Abs(Height-ImageHeight)/2
		, "float", Width, "float", Height, "float", 0, "float", 0, "float", Width, "float", Height, "int", 2
		, "UPtr", 0, "UPtr", 0, "UPtr", 0)
	;;绘文字
	TitleRC:=StrSplit(TextToGraphics_Gdip(G,title, "x" ImageWidth+30 " y" Abs(Height-TitleRC[4]-TextRC[4]-10)/2 " cff" (Dark?"f0f0f0":"333333") " s" TitleFntSize (text=""&&title<>""?"":" Bold "), SystemFontName, TitleRC[3]+30, TitleRC[4]),"|")
	TextRC:=StrSplit(TextToGraphics_Gdip(G,Text, "x" TitleRC[1] " y" TitleRC[2]+TitleRC[4]+5 " cff" (Dark?"e3e3e3":"454545") " s" TextFntSize " ", SystemFontName, TextRC[3]+15, TextRC[4]),"|")
	DllCall("gdiplus\GdipDeleteBrush", "UPtr", pBrush)
	WinGetPos,TrayWndX,TrayWndY,TrayWndW,TrayWndH,ahk_class Shell_TrayWnd
	Loop,% Width
	{
		xpos:=TrayWndW>TrayWndH?A_ScreenWidth-A_Index-15:TrayWndX>0?A_Index+30-Width:A_ScreenWidth-A_Index-30
		ypos:=TrayWndW>TrayWndH?TrayWndY>0?A_ScreenHeight-TrayWndH-Height-15:TrayWndH+15:A_ScreenHeight-TrayWndW-Height-15
		if ((xpos != "") && (ypos != ""))
			VarSetCapacity(pt, 8), NumPut(xpos, pt, 0, "UInt"), NumPut(ypos, pt, 4, "UInt")
		if (Width = "") || (Height = ""){
			size := VarSetCapacity(rect, 16, 0)
			er := DllCall("dwmapi\DwmGetWindowAttribute"
				, "UPtr", hCTT, "UInt", 9, "UPtr", &rect, "UInt", size, "UInt")
			If er
				DllCall("GetWindowRect", "UPtr", hCTT, "UPtr", &rect, "UInt")
			r := []
			r.x1 := NumGet(rect, 0, "Int"), r.y1 := NumGet(rect, 4, "Int")
			r.x2 := NumGet(rect, 8, "Int"), r.y2 := NumGet(rect, 12, "Int")
			r.w := Abs(max(r.x1, r.x2) - min(r.x1, r.x2))
			r.h := Abs(max(r.y1, r.y2) - min(r.y1, r.y2))
			Width := r.w
			Height := r.h
		}
		DllCall("UpdateLayeredWindow", "UPtr", hCTT, "UPtr", 0, "UPtr", ((xpos = "") && (ypos = "")) ? 0 : &pt
			, "int64*", Width|Height<<32, "UPtr", hdc, "int64*", 0, "uint", 0, "UInt*", 255<<16|1<<24, "uint", 2)
	}
	DllCall("SelectObject", "UPtr", hdc, "UPtr", obm),DllCall("DeleteObject", "UPtr", hbm)
	DllCall("DeleteDC", "UPtr", hdc),DllCall("gdiplus\GdipDeleteGraphics", "UPtr", G)
	OnMessage(0x201, "CloseCustomTrayTip")
	if timeout {
		CTTimer := Func("DllCall").Bind("DestroyWindow", "Ptr", hCTT)
		SetTimer, % CTTimer, % "-" . timeout
	}

	Return WinExist("ahk_id " hCTT)?{HWND:hCTT,x:xpos,y:ypos,w:Width,h:Height}:False

	;;格式化字符串自动换行，以免过长
	FormatString:
		loopString:=text=""&&title<>""?title:text
		if !InStr(loopString,"`n"){
			Index:=0,String:=""
			Loop,Parse,loopString
			{
				Index:=A_LoopField~="[\x00-\xff]"?Index+1:Index+2
				String:=Mod(Index,44)=0||Mod(Index,44)=1?String "`n" A_LoopField:String A_LoopField
				String:=RegExReplace(String,"(\n.)[\r\n]","$1")
			}
			if (text=""&&title<>"")
				title:= String<>""?String:title
			Else{
				Text:= String<>""?String:Text
			}
		}
	Return
}

GetAllCNString(ByRef string){
	string:=RegExReplace(string,"[^\x{4E00}-\x{9FFF}\x{3400}-\x{4DB5}\x{20000}-\x{2A6D6}\x{2A700}-\x{2B734}\x{2B740}-\x{2B81F}\x{2B820}-\x{2CEAF}\x{2CEB0}-\x{2EBEF}\x{30000}-\x{3134A}\x{2F00}-\x{2FD5}\x{2E80}-\x{2EF3}\x{F900}-\x{FAD0}\x{2F800}-\x{2FA1D}\x{E815}-\x{E86F}\x{E400}-\x{E5E8}\x{E600}-\x{E6CF}\x{31C0}-\x{31E3}\x{2FF0}-\x{2FFB}\x{3105}-\x{312F}\x{31A0}-\x{31BA}\x{3007}]|[\s\t\r\n]+")

	Return string
}

CloseCustomTrayTip(wParam, lParam, uMsg, hWnd){
	Global hCTT,CTTimer
	DetectHiddenWindows,Off
	if (A_Gui="TT"&&wParam){
		Try {
			SetTimer, % CTTimer,Off
			DllCall("DestroyWindow","ptr",hWnd)
			;;DllCall("user32.dll\PostMessage", "ptr", hWnd, "uint", 0x00A1, "ptr", 2, "ptr", 0)
		}
	}
	DetectHiddenWindows,On
}

TextToGraphics_Gdip(pGraphics, Text, Options, Font:="Arial", Width:="", Height:="", Measure:=0, userBrush:=0, Unit:=0) {
	Static Styles := "Regular|Bold|Italic|BoldItalic|Underline|Strikeout"
		, Alignments := "Near|Left|Centre|Center|Far|Right"
	OWidth := Width,IWidth := Width, IHeight:= Height
	pattern_opts := (A_AhkVersion < "2") ? "iO)" : "i)"
	RegExMatch(Options, pattern_opts "X([\-\d\.]+)(p*)", xpos)
	RegExMatch(Options, pattern_opts "Y([\-\d\.]+)(p*)", ypos)
	RegExMatch(Options, pattern_opts "W([\-\d\.]+)(p*)", PWidth)
	RegExMatch(Options, pattern_opts "H([\-\d\.]+)(p*)", Height)
	RegExMatch(Options, pattern_opts "C(?!(entre|enter))([a-f\d]+)", Colour)
	RegExMatch(Options, pattern_opts "Top|Up|Bottom|Down|vCentre|vCenter", vPos)
	RegExMatch(Options, pattern_opts "NoWrap", NoWrap)
	RegExMatch(Options, pattern_opts "R(\d)", Rendering)
	RegExMatch(Options, pattern_opts "S(\d+)(p*)", Size)
	Width := PWidth
	DllCall("gdiplus\GdipCloneBrush", "UPtr", Colour[2], "UPtr*", pBrushClone)
	if Colour && !DllCall("gdiplus\GdipDeleteBrush", "UPtr", pBrushClone){
		Static Integer := "Integer"
		if Colour[2] is Integer
			PassBrush := 1,pBrush := Colour[2]
	}
	if !(IWidth && IHeight) && ((xpos && xpos[2]) || (ypos && ypos[2]) || (Width && Width[2]) || (Height && Height[2]) || (Size && Size[2]))
		return -1
	Style := 0
	For eachStyle, valStyle in StrSplit(Styles, "|")
	{
		if RegExMatch(Options, "\b" valStyle)
			Style |= (valStyle != "StrikeOut") ? (A_Index-1) : 8
	}
	Align := 0
	For eachAlignment, valAlignment in StrSplit(Alignments, "|")
	{
		if RegExMatch(Options, "\b" valAlignment)
			Align |= A_Index//2.1	; 0|0|1|1|2|2
	}
	xpos := (xpos && (xpos[1] != "")) ? xpos[2] ? IWidth*(xpos[1]/100) : xpos[1] : 0
	ypos := (ypos && (ypos[1] != "")) ? ypos[2] ? IHeight*(ypos[1]/100) : ypos[1] : 0
	Width := (Width && Width[1]) ? Width[2] ? IWidth*(Width[1]/100) : Width[1] : IWidth
	Height := (Height && Height[1]) ? Height[2] ? IHeight*(Height[1]/100) : Height[1] : IHeight
	If !PassBrush
		Colour := "0x" (Colour && Colour[2] ? Colour[2] : "ff000000")
	Rendering := (Rendering && (Rendering[1] >= 0) && (Rendering[1] <= 5)) ? Rendering[1] : 4
	Size := (Size && (Size[1] > 0)) ? Size[2] ? IHeight*(Size[1]/100) : Size[1] : 12
	If RegExMatch(Font, "^(.\:\\.)")
	{
		DllCall("gdiplus\GdipNewPrivateFontCollection", "ptr*", hFontCollection)
		hFontFamily := 0
		E := DllCall("gdiplus\GdipPrivateAddFontFile", "ptr", hFontCollection, "str", Font)
		if !E {
			VarSetCapacity(pFontFamily, 10, 0)
			DllCall("gdiplus\GdipGetFontCollectionFamilyList", "ptr", hFontCollection, "int", 1, "ptr", &pFontFamily, "int*", found)
			VarSetCapacity(FontName, 100)
			DllCall("gdiplus\GdipGetFamilyName", "ptr", NumGet(pFontFamily, 0, "ptr"), "str", FontName, "ushort", 1033)
		}
	} Else DllCall("gdiplus\GdipCreateFontFamilyFromName", "WStr", Font, "uint", 0, "UPtr*", hFontFamily)
	If !hFontFamily
		DllCall("gdiplus\GdipGetGenericFontFamilySansSerif", "UPtr*", hFontFamily)
	DllCall("gdiplus\GdipCreateFont", "UPtr", hFontFamily, "float", Size, "int", Style, "int", Unit, "UPtr*", hFont)
	DllCall("gdiplus\GdipCreateStringFormat", "int", NoWrap ? 0x4000 | 0x1000 : 0x4000, "int", 0, "UPtr*", hStringFormat)
	If !hStringFormat
		DllCall("gdiplus\GdipStringFormatGetGenericTypographic", "UPtr*", hStringFormat)
	if !PassBrush
		DllCall("gdiplus\GdipCreateSolidFill", "UInt", Colour, "UPtr*", pBrush)
	if !(hFontFamily && hFont && hStringFormat && pBrush && pGraphics)
	{
		E := !pGraphics ? -2 : !hFontFamily ? -3 : !hFont ? -4 : !hStringFormat ? -5 : !pBrush ? -6 : 0
		If pBrush
			DllCall("gdiplus\GdipDeleteBrush", "UPtr", pBrush)
		If hStringFormat
			DllCall("gdiplus\GdipDeleteStringFormat", "UPtr", hStringFormat)
		If hFont
			DllCall("gdiplus\GdipDeleteFont", "UPtr", hFont)
		If hFontFamily
			DllCall("gdiplus\GdipDeleteFontFamily", "UPtr", hFontFamily)
		If hFontCollection
			DllCall("gdiplus\GdipDeletePrivateFontCollection", "ptr*", hFontCollection)
		return E
	}
	VarSetCapacity(RC, 16)
	NumPut(xpos, RC, 0, "float"), NumPut(ypos, RC, 4, "float")
	NumPut(Width, RC, 8, "float"), NumPut(Height, RC, 12, "float")
	DllCall("gdiplus\GdipSetStringFormatAlign", "UPtr", hStringFormat, "int", Align)
	If InStr(Options, "autotrim")
		DllCall("gdiplus\GdipSetStringFormatTrimming", "UPtr", hStringFormat, "int", 3)
	DllCall("gdiplus\GdipSetTextRenderingHint", "UPtr", pGraphics, "int", Rendering)
	VarSetCapacity(TempRC, 16)
	DllCall("gdiplus\GdipMeasureString", "UPtr", pGraphics, "WStr", Text, "int", -1
		, "UPtr", hFont, "UPtr", &RC, "UPtr", hStringFormat, "UPtr", &TempRC, "uint*", 0, "uint*", 0)
	ReturnRC := &TempRC ? NumGet(TempRC, 0, "float") "|" NumGet(TempRC, 4, "float") "|" NumGet(TempRC, 8, "float") "|" NumGet(TempRC, 12, "float") "|" 0 "|" 0 : 0
	ReturnRCtest := StrSplit(ReturnRC, "|")
	testX := Floor(ReturnRCtest[1]) - 2
	If (testX>xpos && NoWrap && (PWidth>2 || OWidth>2))
	{
		nxpos := Floor(xpos - (testX - xpos))
		VarSetCapacity(RC, 16)
		NumPut(xpos, RC, 0, "float"), NumPut(ypos, RC, 4, "float")
		NumPut(Width, RC, 8, "float"), NumPut(Height, RC, 12, "float")
		VarSetCapacity(TempRC, 16)
		DllCall("gdiplus\GdipMeasureString", "UPtr", pGraphics, "WStr", Text, "int", -1
			, "UPtr", hFont, "UPtr", &RC, "UPtr", hStringFormat, "UPtr", &TempRC, "uint*", 0, "uint*", 0)
		ReturnRC := &TempRC ? NumGet(TempRC, 0, "float") "|" NumGet(TempRC, 4, "float") "|" NumGet(TempRC, 8, "float") "|" NumGet(TempRC, 12, "float") "|" 0 "|" 0 : 0
	}
	If vPos
	{
		ReturnRC := StrSplit(ReturnRC, "|")
		if (vPos[0] = "vCentre") || (vPos[0] = "vCenter")
			ypos += (Height-ReturnRC[4])//2
		else if (vPos[0] = "Top") || (vPos[0] = "Up")
			ypos += 0
		else if (vPos[0] = "Bottom") || (vPos[0] = "Down")
			ypos += Height-ReturnRC[4]
		VarSetCapacity(RC, 16)
		NumPut(xpos, RC, 0, "float"), NumPut(ypos, RC, 4, "float")
		NumPut(Width, RC, 8, "float"), NumPut(ReturnRC[4], RC, 12, "float")
		VarSetCapacity(TempRC, 16)
		DllCall("gdiplus\GdipMeasureString", "UPtr", pGraphics, "WStr", Text, "int", -1
			, "UPtr", hFont, "UPtr", &RC, "UPtr", hStringFormat, "UPtr", &TempRC, "uint*", 0, "uint*", 0)
		ReturnRC := &TempRC ? NumGet(TempRC, 0, "float") "|" NumGet(TempRC, 4, "float") "|" NumGet(TempRC, 8, "float") "|" NumGet(TempRC, 12, "float") "|" 0 "|" 0 : 0
	}
	thisBrush := userBrush ? userBrush : pBrush
	if !Measure
		_E := DllCall("gdiplus\GdipDrawString", "UPtr", pGraphics, "WStr", Text, "int", -1
			, "UPtr", hFont, "UPtr", &RC, "UPtr", hStringFormat, "UPtr", thisBrush)
	if !PassBrush
		DllCall("gdiplus\GdipDeleteBrush", "UPtr", pBrush)
	DllCall("gdiplus\GdipDeleteStringFormat", "UPtr", hStringFormat)
	DllCall("gdiplus\GdipDeleteFont", "UPtr", hFont)
	DllCall("gdiplus\GdipDeleteFontFamily", "UPtr", hFontFamily)
	If hFontCollection
		DllCall("gdiplus\GdipDeletePrivateFontCollection", "ptr*", hFontCollection)

	return _E ? _E : ReturnRC
}

;获取程序占用内存
GetWorkingSetPrivateSize(PID,Units:= "K"){
	if (DllCall("ntdll.dll\NtQuerySystemInformation", "int", 0x5, "ptr", 0, "uint", 0, "uint*", size) != 0) {
		size := VarSetCapacity(buf, size << 1, 0)
		if (DllCall("ntdll\NtQuerySystemInformation", "int", 0x5, "ptr", &buf, "uint", size, "uint*", 0) != 0){
			memory:=(ErrorLevel := 2) & 0
			return (Units="M"&&memory?(memory//1024) . "M":memory "K")
		}
		addr := &buf
		while (addr) {
			if (NumGet(addr + 80, "ptr") = PID){
				memory:=NumGet(addr + 8, "int64")//1024
				return (Units="M"&&memory?(memory//1024) . "M":memory "K")
			}
			if !(NumGet(addr + 0, "uint"))
				break
			addr+= NumGet(addr + 0, "uint")
		}
	}
	memory:=(ErrorLevel:= 1) & 0
	return (Units="M"&&memory?(memory//1024) . "M":memory "K")
}

;======================================================================================
;;根据进程文件名获取进程信息列表
GetProcessNameList(ProcessName:=""){
	list:="",tarr:=[]
	s := 10240  ; 缓存和数组的大小(4 KB)

	Process, Exist  ; 设置 ErrorLevel 为这个正在运行脚本的 PID.
	; 使用 PROCESS_QUERY_INFORMATION(0x0400) 获取此脚本的句柄:
	h := DllCall("OpenProcess", "UInt", 0x0400, "Int", false, "UInt", ErrorLevel, "Ptr")
	; 打开此进程的可调整的访问令牌(TOKEN_ADJUST_PRIVILEGES = 32):
	DllCall("Advapi32.dll\OpenProcessToken", "Ptr", h, "UInt", 32, "PtrP", t)
	VarSetCapacity(ti, 16, 0)  ; 特权结构
	NumPut(1, ti, 0, "UInt")  ; 特权数组中的一个条目...
	; 获取调试特权的本地唯一标识符:
	DllCall("Advapi32.dll\LookupPrivilegeValue", "Ptr", 0, "Str", "SeDebugPrivilege", "Int64P", luid)
	NumPut(luid, ti, 4, "Int64")
	NumPut(2, ti, 12, "UInt")  ; 启用这个特权: SE_PRIVILEGE_ENABLED = 2
	; 使用新的访问令牌更新此进程的特权:
	r := DllCall("Advapi32.dll\AdjustTokenPrivileges", "Ptr", t, "Int", false, "Ptr", &ti, "UInt", 0, "Ptr", 0, "Ptr", 0)
	DllCall("CloseHandle", "Ptr", t)  ; 关闭此访问令牌句柄以节约内存.
	DllCall("CloseHandle", "Ptr", h)  ; 关闭此进程句柄以节约内存.

	hModule := DllCall("LoadLibrary", "Str", "Psapi.dll")  ; 通过预加载来提升性能.
	s := VarSetCapacity(a, s)  ; 接收进程列表标识符的数组:

	DllCall("Psapi.dll\EnumProcesses", "Ptr", &a, "UInt", s, "UIntP", r)
	Loop, % r // 4  ; 把数组解析为 DWORD(32 位) 的标识符:
	{
		id := NumGet(a, A_Index * 4, "UInt")
		; 打开进程: PROCESS_VM_READ(0x0010) | PROCESS_QUERY_INFORMATION(0x0400)
		h := DllCall("OpenProcess", "UInt", 0x0010 | 0x0400, "Int", false, "UInt", id, "Ptr")
		if !h
			continue
		VarSetCapacity(n, s, 0)  ; 接收模块基础名称的缓存:
		e := DllCall("Psapi.dll\GetModuleBaseName", "Ptr", h, "Ptr", 0, "Str", n, "UInt", A_IsUnicode ? s//2 : s)
		if !e    ;  用于 64 位进程在 32 位模式时的回退方法:
			if e := DllCall("Psapi.dll\GetProcessImageFileName", "Ptr", h, "Str", n, "UInt", A_IsUnicode ? s//2 : s)
				SplitPath n, n
		DllCall("CloseHandle", "Ptr", h)  ; 关闭进程句柄以节约内存
		if (n && e){  ; 如果映像不是空的, 则添加到列表:
			If (ProcessName&&ProcessName=n)
				tarr.push([n,id])
			else
				list.=n "/" id "|"
		}
	}
	DllCall("FreeLibrary", "Ptr", hModule)  ; 卸载库来释放内存.

	return !ProcessName?list:tarr
}

TrayRefresh() {
/*		Remove any dead icon from the tray menu
 *		Should work both for W7 & W10
 */
	WM_MOUSEMOVE := 0x200
	detectHiddenWin := A_DetectHiddenWindows
	DetectHiddenWindows, On
	allTitles := ["ahk_class Shell_TrayWnd"
			, "ahk_class NotifyIconOverflowWindow"]
	allControls := ["ToolbarWindow321"
				,"ToolbarWindow322"
				,"ToolbarWindow323"
				,"ToolbarWindow324"]
	allIconSizes := [24,32]

	for id, title in allTitles {
		for id, controlName in allControls
		{
			for id, iconSize in allIconSizes
			{
				ControlGetPos, xTray,yTray,wdTray,htTray,% controlName,% title
				y := htTray - 10
				While (y > 0)
				{
					x := wdTray - iconSize/2
					While (x > 0)
					{
						point := (y << 16) + x
						PostMessage,% WM_MOUSEMOVE, 0,% point,% controlName,% title
						x -= iconSize/2
					}
					y -= iconSize/2
				}
			}
		}
	}
	DetectHiddenWindows, %detectHiddenWin%
}